package com.rla.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rla.common.constant.RegisterConstants;
import com.rla.common.constant.UserConstants;
import com.rla.common.core.domain.model.LoginAppUser;
import com.rla.common.exception.ServiceException;
import com.rla.common.utils.ServletUtils;
import com.rla.common.utils.StringUtils;
import com.rla.common.wechat.bo.WxBindingPhoneBo;
import com.rla.common.wechat.utils.RestTemplateUtil;
import com.rla.common.wechat.vo.WeChatMiniAuthorizeVo;
import com.rla.domain.IntegralTask;
import com.rla.domain.PointsDetails;
import com.rla.domain.VipUserInfo;
import com.rla.domain.bo.VipUserInfoBo;
import com.rla.domain.vo.VipUserInfoVo;
import com.rla.framework.web.service.TokenService;
import com.rla.mapper.IntegralTaskMapper;
import com.rla.mapper.PointsDetailsMapper;
import com.rla.mapper.VipUserInfoMapper;
import com.rla.system.service.ISysConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@RequiredArgsConstructor
@Slf4j
@Service
public class LoginService {

    private final WeChatService weChatService;
    private final IVipUserInfoService vipUserInfoService;
    private final VipUserInfoMapper vipUserInfoMapper;
    private final TokenService tokenService;
    private final RestTemplateUtil restTemplateUtil;
    private final ISysConfigService configService;
    private final PointsDetailsMapper pointsDetailsMapper;
    private final IntegralTaskMapper integralTaskMapper;

    public String getPhoneByxcxCode(String xcxCode) {
        WeChatMiniAuthorizeVo authorizeVo = weChatService.getAuthorizeVo(xcxCode);
        String openId = authorizeVo.getOpenId();

        VipUserInfoBo paramsBo = new VipUserInfoBo();
        paramsBo.setOpenId(openId);
        List<VipUserInfoVo> list = vipUserInfoService.queryList(paramsBo);
        if (CollUtil.isNotEmpty(list)) {
            VipUserInfoVo vo = list.get(0);
            return vo.getPhone();
        } else {
            return null;
        }
    }


    public WeChatMiniAuthorizeVo getxcxAuthorizeVo(String xcxCode) {
        WeChatMiniAuthorizeVo authorizeVo = weChatService.getAuthorizeVo(xcxCode);
        return authorizeVo;
    }


    public String xcxQuickLogin(WxBindingPhoneBo bo) {
        String phone = weChatService.getUserPhone(bo);
        return xcxPhoneLogin(phone, bo.getOpenid());
    }

    @Transactional(rollbackFor = Exception.class)
    public String xcxPhoneLogin(String phone, String openId) {
        VipUserInfoBo paramsBo = new VipUserInfoBo();
        paramsBo.setPhone(phone);
        List<VipUserInfoVo> list = vipUserInfoService.queryList(paramsBo);

        JSONObject message = new JSONObject();
        //看在中台有无用户信息，无用户信息不允许注册（配置参数开关配置）
        String s = configService.selectConfigByKey(RegisterConstants.IS_CAN_REGISTER);
        if (CollUtil.isEmpty(list) && StrUtil.isNotBlank(s)&& "false".equals(s)) {
            message = this.KHZL(phone);
            if (ObjectUtil.isEmpty(message)){
                throw new ServiceException("未开启非会员注册并无会员信息");
            }
        }

        //存在用户
        if (CollUtil.isNotEmpty(list)) {
            VipUserInfoVo vo = list.get(0);
            LoginAppUser loginUser = new LoginAppUser();
            loginUser.setUserId(Long.parseLong(vo.getId()));
            loginUser.setUserName(vo.getUserName());
            loginUser.setPhone(vo.getPhone());
//            loginUser.setUserType(UserType.APP_USER.getUserType());
//            LoginHelper.loginByDevice(loginUser, DeviceType.APP);
            HttpServletRequest request = ServletUtils.getRequest();
//            asyncService.recordLogininfor(vo.getVipCode(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request);
            recordLoginInfo(vo.getId(), vo.getUserName(), openId);
            return tokenService.createAppToken(loginUser);
        } else {//不存在用户首次注册
            VipUserInfoBo vipUserInfoBo = new VipUserInfoBo();
            if("false".equals(s)){//未开启非会员注册
                message = this.KHZL(phone);
                if (ObjectUtil.isEmpty(message) ){
                    throw new ServiceException("无会员信息");
                }else {
                   this.addUserInfoByDp(vipUserInfoBo,message, phone, openId);
                }
            }else{
                message = this.KHZL(phone);
                if (ObjectUtil.isEmpty(message)){
                    vipUserInfoBo.setPhone(phone);
                    vipUserInfoBo.setOpenId(openId);
                    vipUserInfoBo.setUserName("用户" + phone.substring(phone.length() - 4));
                    vipUserInfoBo.setLoginDate(DateUtil.date());
                    vipUserInfoBo.setLoginIp(ServletUtils.getClientIP());
                    vipUserInfoService.insertByBo(vipUserInfoBo);
                }else {
                    this.addUserInfoByDp(vipUserInfoBo,message, phone, openId);
                    String level = message.getString("level");
                    VipUserInfoBo vui=new VipUserInfoBo();
                    vui.setId(vipUserInfoBo.getId());
                    // 先获取注册积分，然后统一处理
                    Long registrationPoints = this.registrationPoints(vipUserInfoBo);
                    this.operIntegrate(level,vui, registrationPoints);
                }
            }

            // 处理非会员注册的注册积分
            if ("true".equals(s) && ObjectUtil.isEmpty(message)) {
                // 非会员注册，只处理注册积分
                Long registrationPoints = this.registrationPoints(vipUserInfoBo);
                if (registrationPoints > 0) {
                    // 直接更新用户积分
                    VipUserInfo vipUserInfo = vipUserInfoMapper.selectUserUsableIntegral(vipUserInfoBo.getId());
                    Long newUsableIntegral = vipUserInfo.getUsableIntegral() + registrationPoints;
                    Long newSumIntegral = vipUserInfo.getSumIntegral() + registrationPoints;
                    
                    UpdateWrapper<VipUserInfo> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", vipUserInfoBo.getId())
                            .set("usable_integral", newUsableIntegral)
                            .set("sum_integral", newSumIntegral);
                    vipUserInfoMapper.update(null, updateWrapper);
                    
                    // 更新注册积分明细记录
                    LambdaQueryWrapper<PointsDetails> lqw = Wrappers.lambdaQuery(PointsDetails.class)
                            .eq(PointsDetails::getUserId, vipUserInfoBo.getId())
                            .eq(PointsDetails::getTaskId, 12L)
                            .orderByDesc(PointsDetails::getChangeTime)
                            .last("LIMIT 1");
                    List<PointsDetails> registrationDetails = pointsDetailsMapper.selectList(lqw);
                    if (CollectionUtil.isNotEmpty(registrationDetails)) {
                        PointsDetails registrationDetail = registrationDetails.get(0);
                        registrationDetail.setBeforePoints(vipUserInfo.getUsableIntegral());
                        registrationDetail.setAfterPoints(newUsableIntegral);
                        pointsDetailsMapper.updateById(registrationDetail);
                    }
                }
            }

            LoginAppUser loginUser = new LoginAppUser();
            loginUser.setUserId(Long.parseLong(vipUserInfoBo.getId()));
            loginUser.setUserName(vipUserInfoBo.getUserName());
            loginUser.setPhone(vipUserInfoBo.getPhone());
            HttpServletRequest request = ServletUtils.getRequest();
//            asyncService.recordLogininfor(VipUserInfoBo.getVipCode(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request);
            return tokenService.createAppToken(loginUser);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void operIntegrate(String level, VipUserInfoBo vipUserInfoBo, Long registrationPoints) {
        // 获取VIP等级对应的积分值
        Map<Integer, Integer> levelToPoints = new HashMap<>();
        levelToPoints.put(1, UserConstants.VIP1);
        levelToPoints.put(2, UserConstants.VIP2);
        levelToPoints.put(3, UserConstants.VIP3);
        levelToPoints.put(4, UserConstants.VIP4);
        levelToPoints.put(5, UserConstants.VIP5);
        levelToPoints.put(6, UserConstants.VIP6);
        levelToPoints.put(7, UserConstants.VIP7);

        int levelInt = Integer.parseInt(level);
        Integer vipValue = levelToPoints.get(levelInt);
        if (vipValue == null) {
            throw new IllegalArgumentException("无效: " + level);
        }

        // 获取用户当前积分
        VipUserInfo vipUserInfo = vipUserInfoMapper.selectUserUsableIntegral(vipUserInfoBo.getId());
        
        // 计算总积分：VIP等级积分 + 注册积分
        Long totalPoints = vipValue + (registrationPoints != null ? registrationPoints : 0L);
        Long newUsableIntegral = vipUserInfo.getUsableIntegral() + totalPoints;
        Long newSumIntegral = vipUserInfo.getSumIntegral() + totalPoints;

        //更新用户积分
        UpdateWrapper<VipUserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", vipUserInfoBo.getId())
                .set("usable_integral", newUsableIntegral)
                .set("sum_integral", newSumIntegral);
        vipUserInfoMapper.update(null, updateWrapper);

        // 创建VIP等级积分明细记录
        PointsDetails pointsDetails = new PointsDetails();
        pointsDetails.setUserId(vipUserInfoBo.getId());
        pointsDetails.setVariablePoints((long) vipValue);
        pointsDetails.setBeforePoints(vipUserInfo.getUsableIntegral());
        pointsDetails.setAfterPoints(vipUserInfo.getUsableIntegral() + vipValue);
        pointsDetails.setCreateBy(vipUserInfoBo.getId());
        pointsDetails.setCreateTime(new Date());
        pointsDetails.setChangeType("5");
        pointsDetails.setTask("初始化积分");
        pointsDetails.setChangeTime(new Date());
        pointsDetailsMapper.insert(pointsDetails);
        
        // 如果有注册积分，更新注册积分明细记录的beforePoints和afterPoints
        if (registrationPoints != null && registrationPoints > 0) {
            LambdaQueryWrapper<PointsDetails> lqw = Wrappers.lambdaQuery(PointsDetails.class)
                    .eq(PointsDetails::getUserId, vipUserInfoBo.getId())
                    .eq(PointsDetails::getTaskId, 12L)
                    .orderByDesc(PointsDetails::getChangeTime)
                    .last("LIMIT 1");
            List<PointsDetails> registrationDetails = pointsDetailsMapper.selectList(lqw);
            if (CollectionUtil.isNotEmpty(registrationDetails)) {
                PointsDetails registrationDetail = registrationDetails.get(0);
                registrationDetail.setBeforePoints(vipUserInfo.getUsableIntegral() + vipValue);
                registrationDetail.setAfterPoints(newUsableIntegral);
                pointsDetailsMapper.updateById(registrationDetail);
            }
        }
    }




    //首次注册赠送积分完成积分任务
    @Transactional(rollbackFor = Exception.class)
    public Long registrationPoints(VipUserInfoBo vipUserInfoBo){
        LambdaQueryWrapper<IntegralTask> lqw = Wrappers.lambdaQuery(IntegralTask.class)
                .eq(IntegralTask::getIsShow, "1");
        List<IntegralTask> integralTasks = integralTaskMapper.selectList(lqw);

        List<IntegralTask> list1 = integralTasks.stream().filter(item->item.getID()==12).collect(Collectors.toList());

        //用户有效注册
        if (CollectionUtil.isNotEmpty(list1)){
            LambdaQueryWrapper<PointsDetails> lqw1 = Wrappers.lambdaQuery(PointsDetails.class)
                    .eq(PointsDetails::getUserId, vipUserInfoBo.getId())
                    .eq(PointsDetails::getTaskId, 12L);
            List<PointsDetails> list = pointsDetailsMapper.selectList(lqw1);

            if (CollectionUtil.isEmpty(list)){
                // 只创建积分明细记录，不直接更新用户积分
                PointsDetails pointsDetails = new PointsDetails();
                pointsDetails.setUserId(vipUserInfoBo.getId().toString());
                pointsDetails.setVariablePoints(list1.get(0).getRewardsPoints());
                pointsDetails.setOperator(vipUserInfoBo.getId().toString());
                pointsDetails.setChangeTime(new Date());
                pointsDetails.setChangeType("5");
                pointsDetails.setTask("用户有效注册");
                pointsDetails.setUserName(vipUserInfoBo.getUserName());
                pointsDetails.setPhone(vipUserInfoBo.getPhone());
                pointsDetails.setTaskId(12L);
                pointsDetailsMapper.insert(pointsDetails);
                
                // 返回需要添加的积分值，由调用方统一处理
                return list1.get(0).getRewardsPoints();
            }
        }
        return 0L;
    }


    @Transactional(rollbackFor = Exception.class)
    public void addUserInfoByDp(VipUserInfoBo vipUserInfoBo,JSONObject message,String phone, String openId) {
        String vipCode = message.getString("vip_code");
        String userName = message.getString("user_name");
        String sex = message.getString("sex");
        String birthday = message.getString("birthday");
        String height = message.getString("height");
        String weight = message.getString("weight");
        String province = message.getString("province");
        String city = message.getString("city");
        String county = message.getString("county");
        String addressDetail = message.getString("address_detail");
        String usableBalance = message.getString("usable_balance");
        String department = message.getString("department");
        String business = message.getString("business");
        String businessName = message.getString("business_name");
        String departmentName = message.getString("department_name");
        String level = message.getString("level");

        vipUserInfoBo.setVipCode(StringUtils.isNotEmpty(vipCode)?vipCode:"");
        vipUserInfoBo.setDpId(StringUtils.isNotEmpty(vipCode)?vipCode:"");
        vipUserInfoBo.setUserName(StringUtils.isNotEmpty(userName)?userName:"");
        vipUserInfoBo.setSex(StringUtils.isNotEmpty(sex)?(sex.equals("男")?"1":"0"):"");
        vipUserInfoBo.setPhone(phone);
        vipUserInfoBo.setBirthday(StringUtils.isNotEmpty(birthday)?birthday.split("")[0]:"");
        vipUserInfoBo.setHeight(StringUtils.isNotEmpty(height)?height:"");
        vipUserInfoBo.setWeight(StringUtils.isNotEmpty(weight)?weight:"");
        vipUserInfoBo.setProvince(StringUtils.isNotEmpty(province)?province:"");
        vipUserInfoBo.setCity(StringUtils.isNotEmpty(city)?city:"");
        vipUserInfoBo.setCounty(StringUtils.isNotEmpty(county)?county:"");
        vipUserInfoBo.setAddressDetail(StringUtils.isNotEmpty(addressDetail)?addressDetail:"");
        vipUserInfoBo.setUsableBalance(StringUtils.isNotEmpty(usableBalance)?new BigDecimal(usableBalance):new BigDecimal(0));
        vipUserInfoBo.setSumBalance(StringUtils.isNotEmpty(usableBalance)?new BigDecimal(usableBalance):new BigDecimal(0));
        vipUserInfoBo.setFreezeBalance(new BigDecimal(0));
        vipUserInfoBo.setDepartment(StringUtils.isNotEmpty(department)?department:"");
        vipUserInfoBo.setBusiness(StringUtils.isNotEmpty(business)?business:"");
        vipUserInfoBo.setBusinessName(StringUtils.isNotEmpty(businessName)?businessName:"");
        vipUserInfoBo.setBusinessName(StringUtils.isNotEmpty(departmentName)?departmentName:"");
        vipUserInfoBo.setIsAuth("1");
        vipUserInfoBo.setIsDpSync("1");
        vipUserInfoBo.setVipGradeCode(level);

        vipUserInfoBo.setOpenId(openId);
        vipUserInfoService.insertByBo(vipUserInfoBo);
    }


    public JSONObject KHZL(String phone){
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("SJHM", phone);
        String data = restTemplateUtil.postMapData(RegisterConstants.KHZL, map);
        JSONObject jsonObject = JSON.parseObject(data);
        return jsonObject.getJSONObject("Message");
    }


    /**
     * 记录登录信息
     *
     * @param id 用户ID
     */
    public void recordLoginInfo(String id, String username, String openId) {
        vipUserInfoMapper.update(null, Wrappers.lambdaUpdate(VipUserInfo.class)
                .set(VipUserInfo::getLoginDate, DateUtil.now())
                .set(VipUserInfo::getLoginIp, ServletUtils.getClientIP())
                .set(StrUtil.isNotBlank(openId), VipUserInfo::getOpenId, openId)
                .eq(VipUserInfo::getId, id));

    }

}
